//
// Created by Administrator on 2025/4/12.
//

#include "StateMachine.h"

StateMachine::StateMachine()
:_curState(nullptr)
,_preState(nullptr)
,_errState(nullptr)
,_errorHandler(nullptr)
,_transitionInProgress(false)
{

}

StateMachine::~StateMachine() {
    //无论是什么状态
    //这里都没有所有权，所以不负责删除
    //看能不能理解，这只是一个机器，机器有不同的状态，有事件，就处理
    //举个例子
    //一个机器朝 "东、南、西、北" （有不同的状态）
    //当有前进指令(事件),就前进(处理)
    //朝向不同，状态不同，而东南西北并不是机器管理，只是拥有这个状态，所以不负责删除状态
}

bool StateMachine::initStateMachine(BaseState* initialState,BaseState* errorState) {
    if(initialState == nullptr || errorState == nullptr ){
        return false;
    }
    _curState = initialState;
    _errState = errorState;

    try{
        //进入初始状态
        _curState->onEntry();
        return true;
    }catch(...) {
        handleError(1, "进入初始状态失败！");
        return false;
    }
}

bool StateMachine::handleEvent(const Event *event) {
    if(event == nullptr){
        return false;
    }

    //确保不会让同一事件出发两次
    if(_transitionInProgress == true){
        return false;
    }

    try{
        //标记该事件得到处理
        _transitionInProgress = true;
        //本章虚函数核心，调用基类方法，基类去调用子类方法
        bool ok = _curState->handleEvent(this,event);
        //处理过了
        _transitionInProgress = false;
        return ok;
    }catch (...){
        _transitionInProgress = false;
        handleError(2, "事件处理异常");
        return false;
    }
}

bool StateMachine::changeState(BaseState* newState) {
    if(newState == nullptr){
        return false;
    }
    try{
        if(_curState != nullptr){
            //调用当前状态离开方法
            _curState->onExit();
        }
        //调用当前状态离开方法
        _preState = _curState;
        _curState = newState;
        //进入下一个状态
        _curState->onEntry();
        return true;
    }catch (...){
        handleError(3, "切换状态失败");
        return false;
    }
}

bool StateMachine::transitionToPreState() {
    if(_preState == nullptr)
        return false;
    return changeState(_preState);
}

void StateMachine::setErrorHandler(ErrorHandler errorHandler) {
    //用户设置回调函数
    _errorHandler = errorHandler;
}

void StateMachine::handleError(int errID, std::string errMsg) {
    if(_errorHandler != nullptr){
        _errorHandler(errID,errMsg);
    }
    // 如果有错误状态，切换到错误状态
    if (_errState && _curState != _errState) {
        changeState(_errState);
    }
}

BaseState *StateMachine::getCurrentState() const {
    if(_curState != nullptr){
        return _curState;
    }
    return nullptr;
}
